package com.javaxiaobear.module.system.mapper;

import static com.javaxiaobear.module.system.domain.table.SysDeptTableDef.SYS_DEPT;
import static com.javaxiaobear.module.system.domain.table.SysRoleTableDef.SYS_ROLE;
import static com.javaxiaobear.module.system.domain.table.SysUserRoleTableDef.SYS_USER_ROLE;
import static com.javaxiaobear.module.system.domain.table.SysUserTableDef.SYS_USER;

import com.javaxiaobear.base.common.utils.PageUtils;
import com.javaxiaobear.module.system.domain.SysUser;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.annotations.Param;

/**
 * 用户表 数据层
 *
 * @author javaxiaobear
 */
public interface SysUserMapper extends BaseMapper<SysUser> {

  /** 根据条件分页查询用户列表 */
  default List<SysUser> selectUserList(SysUser sysUser) {
    var query =
        QueryChain.of(this)
            .select(
                SYS_USER.USER_ID,
                SYS_USER.DEPT_ID,
                SYS_USER.NICK_NAME,
                SYS_USER.USER_NAME,
                SYS_USER.EMAIL,
                SYS_USER.AVATAR,
                SYS_USER.PHONENUMBER,
                SYS_USER.SEX,
                SYS_USER.STATUS,
                SYS_USER.DEL_FLAG,
                SYS_USER.LOGIN_IP,
                SYS_USER.LOGIN_DATE,
                SYS_USER.CREATE_BY,
                SYS_USER.CREATE_TIME,
                SYS_USER.REMARK,
                SYS_DEPT.DEPT_NAME,
                SYS_DEPT.LEADER)
            .from(SYS_USER)
            .leftJoin(SYS_DEPT)
            .on(SYS_USER.DEPT_ID.eq(SYS_DEPT.DEPT_ID))
            .where(SYS_USER.DEL_FLAG.eq("0"))
            .and(
                SYS_USER
                    .USER_ID
                    .eq(sysUser.getUserId())
                    .when(sysUser.getUserId() != null && sysUser.getUserId() != 0))
            .and(
                SYS_USER
                    .USER_NAME
                    .like(sysUser.getUserName())
                    .when(sysUser.getUserName() != null && !sysUser.getUserName().isEmpty()))
            .and(
                SYS_USER
                    .STATUS
                    .eq(sysUser.getStatus())
                    .when(sysUser.getStatus() != null && !sysUser.getStatus().isEmpty()))
            .and(
                SYS_USER
                    .PHONENUMBER
                    .like(sysUser.getPhonenumber())
                    .when(sysUser.getPhonenumber() != null && !sysUser.getPhonenumber().isEmpty()));

    // 处理日期范围检索
    if (sysUser.getParams() != null) {
      String beginTime = (String) sysUser.getParams().get("beginTime");
      String endTime = (String) sysUser.getParams().get("endTime");

      if (beginTime != null && !beginTime.isEmpty()) {
        query.and(SYS_USER.CREATE_TIME.ge(parseDate(beginTime)));
      }

      if (endTime != null && !endTime.isEmpty()) {
        query.and(SYS_USER.CREATE_TIME.le(parseDate(endTime)));
      }

      // 数据范围过滤 - 注意：这里简化处理，实际应用中需要根据具体的dataScope实现
      String dataScope = (String) sysUser.getParams().get("dataScope");
      // 如果dataScope不为空，可以在这里添加相应的条件
    }

    // 部门ID过滤（包含子部门）
    if (sysUser.getDeptId() != null && sysUser.getDeptId() != 0) {
      // 这里简化处理，实际应用中需要根据部门表的结构实现find_in_set逻辑
      query.and(SYS_USER.DEPT_ID.eq(sysUser.getDeptId()));
      // 完整实现应该包含子部门的查询逻辑
    }

    return query.list();
  }

  default Page<SysUser> selectUserPage(SysUser sysUser) {
    var query =
        QueryChain.of(this)
            .select(
                SYS_USER.USER_ID,
                SYS_USER.DEPT_ID,
                SYS_USER.NICK_NAME,
                SYS_USER.USER_NAME,
                SYS_USER.EMAIL,
                SYS_USER.AVATAR,
                SYS_USER.PHONENUMBER,
                SYS_USER.SEX,
                SYS_USER.STATUS,
                SYS_USER.DEL_FLAG,
                SYS_USER.LOGIN_IP,
                SYS_USER.LOGIN_DATE,
                SYS_USER.CREATE_BY,
                SYS_USER.CREATE_TIME,
                SYS_USER.REMARK,
                SYS_DEPT.DEPT_NAME,
                SYS_DEPT.LEADER)
            .from(SYS_USER)
            .leftJoin(SYS_DEPT)
            .on(SYS_USER.DEPT_ID.eq(SYS_DEPT.DEPT_ID))
            .where(SYS_USER.DEL_FLAG.eq("0"))
            .and(
                SYS_USER
                    .USER_ID
                    .eq(sysUser.getUserId())
                    .when(sysUser.getUserId() != null && sysUser.getUserId() != 0))
            .and(
                SYS_USER
                    .USER_NAME
                    .like(sysUser.getUserName())
                    .when(sysUser.getUserName() != null && !sysUser.getUserName().isEmpty()))
            .and(
                SYS_USER
                    .STATUS
                    .eq(sysUser.getStatus())
                    .when(sysUser.getStatus() != null && !sysUser.getStatus().isEmpty()))
            .and(
                SYS_USER
                    .PHONENUMBER
                    .like(sysUser.getPhonenumber())
                    .when(sysUser.getPhonenumber() != null && !sysUser.getPhonenumber().isEmpty()));

    // 处理日期范围检索
    if (sysUser.getParams() != null) {
      String beginTime = (String) sysUser.getParams().get("beginTime");
      String endTime = (String) sysUser.getParams().get("endTime");

      if (beginTime != null && !beginTime.isEmpty()) {
        query.and(SYS_USER.CREATE_TIME.ge(parseDate(beginTime)));
      }

      if (endTime != null && !endTime.isEmpty()) {
        query.and(SYS_USER.CREATE_TIME.le(parseDate(endTime)));
      }

      // 数据范围过滤 - 注意：这里简化处理，实际应用中需要根据具体的dataScope实现
      String dataScope = (String) sysUser.getParams().get("dataScope");
      // 如果dataScope不为空，可以在这里添加相应的条件
    }

    // 部门ID过滤（包含子部门）
    if (sysUser.getDeptId() != null && sysUser.getDeptId() != 0) {
      // 这里简化处理，实际应用中需要根据部门表的结构实现find_in_set逻辑
      query.and(SYS_USER.DEPT_ID.eq(sysUser.getDeptId()));
      // 完整实现应该包含子部门的查询逻辑
    }

    return query.page(PageUtils.getPage());
  }

  /** 根据条件分页查询已配用户角色列表 */
  default Page<SysUser> selectAllocatedList(SysUser user) {
    return QueryChain.of(this)
        .select(
            SYS_USER.USER_ID,
            SYS_USER.DEPT_ID,
            SYS_USER.USER_NAME,
            SYS_USER.NICK_NAME,
            SYS_USER.EMAIL,
            SYS_USER.PHONENUMBER,
            SYS_USER.STATUS,
            SYS_USER.CREATE_TIME)
        .from(SYS_USER)
        .leftJoin(SYS_DEPT)
        .on(SYS_USER.DEPT_ID.eq(SYS_DEPT.DEPT_ID))
        .leftJoin(SYS_USER_ROLE)
        .on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID))
        .leftJoin(SYS_ROLE)
        .on(SYS_ROLE.ROLE_ID.eq(SYS_USER_ROLE.ROLE_ID))
        .where(SYS_USER.DEL_FLAG.eq("0"))
        .and(SYS_ROLE.ROLE_ID.eq(user.getRoleId()))
        .and(
            SYS_USER
                .USER_NAME
                .like(user.getUserName())
                .when(user.getUserName() != null && !user.getUserName().isEmpty()))
        .and(
            SYS_USER
                .PHONENUMBER
                .like(user.getPhonenumber())
                .when(user.getPhonenumber() != null && !user.getPhonenumber().isEmpty()))
        .page(PageUtils.getPage());
  }

  /** 根据条件分页查询未分配用户角色列表 */
  default Page<SysUser> selectUnallocatedList(SysUser user) {
    return QueryChain.of(this)
        .select(
            SYS_USER.USER_ID,
            SYS_USER.DEPT_ID,
            SYS_USER.USER_NAME,
            SYS_USER.NICK_NAME,
            SYS_USER.EMAIL,
            SYS_USER.PHONENUMBER,
            SYS_USER.STATUS,
            SYS_USER.CREATE_TIME)
        .from(SYS_USER)
        .leftJoin(SYS_DEPT)
        .on(SYS_USER.DEPT_ID.eq(SYS_DEPT.DEPT_ID))
        .leftJoin(SYS_USER_ROLE)
        .on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID))
        .leftJoin(SYS_ROLE)
        .on(SYS_ROLE.ROLE_ID.eq(SYS_USER_ROLE.ROLE_ID))
        .where(SYS_USER.DEL_FLAG.eq("0"))
        .and((SYS_ROLE.ROLE_ID.ne(user.getRoleId())).or(SYS_ROLE.ROLE_ID.isNull()))
        .and(
            SYS_USER
                .USER_NAME
                .like(user.getUserName())
                .when(user.getUserName() != null && !user.getUserName().isEmpty()))
        .and(
            SYS_USER
                .PHONENUMBER
                .like(user.getPhonenumber())
                .when(user.getPhonenumber() != null && !user.getPhonenumber().isEmpty()))
        .and(
            SYS_USER.USER_ID.notIn(
                QueryWrapper.create()
                    .select(SYS_USER.USER_ID)
                    .from(SYS_USER)
                    .innerJoin(SYS_USER_ROLE)
                    .on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID))
                    .where(SYS_USER_ROLE.ROLE_ID.eq(user.getRoleId()))))
        .page(PageUtils.getPage());
  }

  /** 通过用户名查询用户 */
  default SysUser selectUserByUserName(String userName) {
    return QueryChain.of(this)
        .select(
            SYS_USER.USER_ID,
            SYS_USER.DEPT_ID,
            SYS_USER.USER_NAME,
            SYS_USER.NICK_NAME,
            SYS_USER.EMAIL,
            SYS_USER.PHONENUMBER,
            SYS_USER.SEX,
            SYS_USER.AVATAR,
            SYS_USER.PASSWORD,
            SYS_USER.STATUS,
            SYS_USER.DEL_FLAG,
            SYS_USER.LOGIN_IP,
            SYS_USER.LOGIN_DATE,
            SYS_USER.CREATE_BY,
            SYS_USER.CREATE_TIME,
            SYS_USER.REMARK,
            SYS_DEPT.DEPT_ID,
            SYS_DEPT.PARENT_ID,
            SYS_DEPT.ANCESTORS,
            SYS_DEPT.DEPT_NAME,
            SYS_DEPT.ORDER_NUM,
            SYS_DEPT.LEADER,
            SYS_DEPT.STATUS.as("dept_status"),
            SYS_ROLE.ROLE_ID,
            SYS_ROLE.ROLE_NAME,
            SYS_ROLE.ROLE_KEY,
            SYS_ROLE.ROLE_SORT,
            SYS_ROLE.DATA_SCOPE,
            SYS_ROLE.STATUS.as("role_status"))
        .from(SYS_USER)
        .leftJoin(SYS_DEPT)
        .on(SYS_USER.DEPT_ID.eq(SYS_DEPT.DEPT_ID))
        .leftJoin(SYS_USER_ROLE)
        .on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID))
        .leftJoin(SYS_ROLE)
        .on(SYS_ROLE.ROLE_ID.eq(SYS_USER_ROLE.ROLE_ID))
        .where(SYS_USER.USER_NAME.eq(userName))
        .and(SYS_USER.DEL_FLAG.eq("0"))
        .one();
  }

  /** 通过用户ID查询用户 */
  default SysUser selectUserById(Long userId) {
    return selectOneWithRelationsById(userId);
  }

  /** 新增用户信息 */
  default int insertUser(SysUser user) {
    return insert(user);
  }

  /** 修改用户信息 */
  default int updateUser(SysUser user) {
    return update(user);
  }

  /** 修改用户头像 */
  default boolean updateUserAvatar(
      @Param("userName") String userName, @Param("avatar") String avatar) {
    return UpdateChain.of(this)
        .set(SYS_USER.AVATAR, avatar)
        .where(SYS_USER.USER_NAME.eq(userName))
        .update();
  }

  /** 重置用户密码 */
  default boolean resetUserPwd(
      @Param("userName") String userName, @Param("password") String password) {
    return UpdateChain.of(this)
        .set(SYS_USER.PASSWORD, password)
        .where(SYS_USER.USER_NAME.eq(userName))
        .update();
  }

  /** 通过用户ID删除用户（逻辑删除） */
  default boolean deleteUserById(Long userId) {
    return UpdateChain.of(this)
        .set(SYS_USER.DEL_FLAG, "2")
        .where(SYS_USER.USER_ID.eq(userId))
        .update();
  }

  /** 批量删除用户信息（逻辑删除） */
  default int deleteUserByIds(Long[] userIds) {
    if (userIds == null || userIds.length == 0) {
      return 0;
    }
    return deleteByCondition(SYS_USER.USER_ID.in(Arrays.asList(userIds)));
  }

  /** 校验用户名称是否唯一 */
  default SysUser checkUserNameUnique(String userName) {
    QueryWrapper queryWrapper =
        QueryWrapper.create()
            .select(SYS_USER.USER_ID, SYS_USER.USER_NAME)
            .where(SYS_USER.USER_NAME.eq(userName))
            .and(SYS_USER.DEL_FLAG.eq("0"))
            .limit(1);
    return selectOneByQuery(queryWrapper);
  }

  /** 校验手机号码是否唯一 */
  default SysUser checkPhoneUnique(String phonenumber) {
    QueryWrapper queryWrapper =
        QueryWrapper.create()
            .select(SYS_USER.USER_ID, SYS_USER.PHONENUMBER)
            .where(SYS_USER.PHONENUMBER.eq(phonenumber))
            .and(SYS_USER.DEL_FLAG.eq("0"))
            .limit(1);
    return selectOneByQuery(queryWrapper);
  }

  /** 校验email是否唯一 */
  default SysUser checkEmailUnique(String email) {
    QueryWrapper queryWrapper =
        QueryWrapper.create()
            .select(SYS_USER.USER_ID, SYS_USER.EMAIL)
            .where(SYS_USER.EMAIL.eq(email))
            .and(SYS_USER.DEL_FLAG.eq("0"))
            .limit(1);
    return selectOneByQuery(queryWrapper);
  }

  /** 辅助方法：解析日期字符串为Date对象 */
  private Date parseDate(String dateStr) {
    try {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      return sdf.parse(dateStr);
    } catch (Exception e) {
      return null;
    }
  }
}
